<?xml version="1.0" encoding="utf-8" standalone="no"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
        "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <link href="../Styles/style.css" rel="stylesheet" type="text/css"/>


</head>

<body>
<div class="article-body">
    <div class="article-intro">

        <h1>Java 接口</h1>


        <p>接口（英文：Interface），在JAVA编程语言中是一个抽象类型，是抽象方法的集合，接口通常以interface来声明。一个类通过继承接口的方式，从而来继承接口的抽象方法。</p>
        <p>接口并不是类，编写接口的方式和类很相似，但是它们属于不同的概念。类描述对象的属性和方法。接口则包含类要实现的方法。</p>
        <p>除非实现接口的类是抽象类，否则该类要定义接口中的所有方法。</p>
        <p>接口无法被实例化，但是可以被实现。一个实现接口的类，必须实现接口内所描述的所有方法，否则就必须声明为抽象类。另外，在 Java 中，接口类型可用来声明一个变量，他们可以成为一个空指针，或是被绑定在一个以此接口实现的对象。</p>
        <h3>接口与类相似点：</h3>
        <ul>
            <li>
                一个接口可以有多个方法。</li>
            <li>
                接口文件保存在 .java 结尾的文件中，文件名使用接口名。</li>
            <li>
                接口的字节码文件保存在 .class 结尾的文件中。</li>
            <li>
                接口相应的字节码文件必须在与包名称相匹配的目录结构中。</li>
        </ul><h3>
        接口与类的区别：</h3>
        <ul>
            <li>
                接口不能用于实例化对象。</li>
            <li>
                接口没有构造方法。</li>
            <li>
                接口中所有的方法必须是抽象方法。</li>
            <li>
                接口不能包含成员变量，除了 static 和 final 变量。</li>
            <li>
                接口不是被类继承了，而是要被类实现。</li>
            <li>
                接口支持多继承。</li>
        </ul>
        <h3>接口特性</h3>
        <ul>
            <li>接口中每一个方法也是隐式抽象的,接口中的方法会被隐式的指定为 <strong>public abstract</strong>（只能是  public abstract，其他修饰符都会报错）。</li>
            <li>接口中可以含有变量，但是接口中的变量会被隐式的指定为 <strong>public static final</strong> 变量（并且只能是 public，用 private 修饰会报编译错误）。</li>
            <li>接口中的方法是不能在接口中实现的，只能由实现接口的类来实现接口中的方法。</li>
        </ul>

        <h3>抽象类和接口的区别</h3>
        <ul><li>
            1. 抽象类中的方法可以有方法体，就是能实现方法的具体功能，但是接口中的方法不行。</li><li>
            2. 抽象类中的成员变量可以是各种类型的，而接口中的成员变量只能是 <strong>public static final</strong> 类型的。</li><li>
            3. 接口中不能含有静态代码块以及静态方法(用 static 修饰的方法)，而抽象类是可以有静态代码块和静态方法。</li><li>
            4. 一个类只能继承一个抽象类，而一个类却可以实现多个接口。</li>

        </ul>
        <hr><h2>接口的声明</h2>
        <p>接口的声明语法格式如下：</p>
        <div class="example">
            <div class="example_code">
                <pre class="hl-main"><span class="hl-brackets">[</span><span class="hl-code">可见度</span><span class="hl-brackets">]</span><span class="hl-code"> </span><span class="hl-reserved">interface</span><span class="hl-code"> 接口名称 </span><span class="hl-brackets">[</span><span class="hl-reserved">extends</span><span class="hl-code"> 其他的类名</span><span class="hl-brackets">]</span><span class="hl-code"> </span><span class="hl-brackets">{</span><span class="hl-code">
        </span><span class="hl-comment">//</span><span class="hl-comment"> 声明变量</span><span class="hl-comment"></span><span class="hl-code">
        </span><span class="hl-comment">//</span><span class="hl-comment"> 抽象方法</span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-brackets">}</span></pre>
            </div>
        </div>
        <p>Interface关键字用来声明一个接口。下面是接口声明的一个简单例子。</p>
        <div class="example">
            <h2 class="example">NameOfInterface.java 文件代码：</h2>
            <div class="example_code">
                <pre class="hl-main"><span class="hl-comment">/*</span><span class="hl-comment"> 文件名 : NameOfInterface.java </span><span class="hl-comment">*/</span><span class="hl-code">
</span><span class="hl-reserved">import</span><span class="hl-code"> </span><span class="hl-identifier">java</span><span class="hl-code">.</span><span class="hl-identifier">lang</span><span class="hl-code">.*;
</span><span class="hl-comment">//</span><span class="hl-comment">引入包</span><span class="hl-comment"></span><span class="hl-code">

</span><span class="hl-reserved">public</span><span class="hl-code"> </span><span class="hl-reserved">interface</span><span class="hl-code"> </span><span class="hl-identifier">NameOfInterface</span><span class="hl-code">
</span><span class="hl-brackets">{</span><span class="hl-code">
   </span><span class="hl-comment">//</span><span class="hl-comment">任何类型 final, static 字段</span><span class="hl-comment"></span><span class="hl-code">
   </span><span class="hl-comment">//</span><span class="hl-comment">抽象方法</span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-brackets">}</span></pre>
            </div>
        </div>
        <p></p>接口有以下特性：<p></p>
        <ul>
            <li>
                接口是隐式抽象的，当声明一个接口的时候，不必使用<strong>abstract</strong>关键字。</li>
            <li>
                接口中每一个方法也是隐式抽象的，声明时同样不需要<strong>abstract</strong>关键字。</li>
            <li>
                接口中的方法都是公有的。</li>
        </ul>
        <h3>实例</h3>
        <div class="example">
            <h2 class="example">Animal.java 文件代码：</h2>
            <div class="example_code">
                <pre class="hl-main"><span class="hl-comment">/*</span><span class="hl-comment"> 文件名 : Animal.java </span><span class="hl-comment">*/</span><span class="hl-code">
</span><span class="hl-reserved">interface</span><span class="hl-code"> </span><span class="hl-identifier">Animal</span><span class="hl-code"> </span><span class="hl-brackets">{</span><span class="hl-code">
   </span><span class="hl-reserved">public</span><span class="hl-code"> </span><span class="hl-types">void</span><span class="hl-code"> </span><span class="hl-identifier">eat</span><span class="hl-brackets">(</span><span class="hl-brackets">)</span><span class="hl-code">;
   </span><span class="hl-reserved">public</span><span class="hl-code"> </span><span class="hl-types">void</span><span class="hl-code"> </span><span class="hl-identifier">travel</span><span class="hl-brackets">(</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-brackets">}</span></pre>
            </div>
        </div>
        <hr><h2>接口的实现</h2>

        <p>当类实现接口的时候，类要实现接口中所有的方法。否则，类必须声明为抽象的类。</p>
        <p>类使用implements关键字实现接口。在类声明中，Implements关键字放在class声明后面。</p>
        <p>实现一个接口的语法，可以使用这个公式：</p>
        <div class="example">
            <h2 class="example">Animal.java 文件代码：</h2>
            <div class="example_code">
                <pre class="hl-main"><span class="hl-code">...</span><span class="hl-reserved">implements</span><span class="hl-code"> 接口名称</span><span class="hl-brackets">[</span><span class="hl-code">, 其他接口名称, 其他接口名称..., ...</span><span class="hl-brackets">]</span><span class="hl-code"> ...</span></pre>
            </div>
        </div>
        <h3>实例</h3>
        <div class="example">
            <h2 class="example">MammalInt.java 文件代码：</h2>
            <div class="example_code">
                <pre class="hl-main"><span class="hl-comment">/*</span><span class="hl-comment"> 文件名 : MammalInt.java </span><span class="hl-comment">*/</span><span class="hl-code">
</span><span class="hl-reserved">public</span><span class="hl-code"> </span><span class="hl-reserved">class</span><span class="hl-code"> </span><span class="hl-identifier">MammalInt</span><span class="hl-code"> </span><span class="hl-reserved">implements</span><span class="hl-code"> </span><span class="hl-identifier">Animal</span><span class="hl-brackets">{</span><span class="hl-code">

   </span><span class="hl-reserved">public</span><span class="hl-code"> </span><span class="hl-types">void</span><span class="hl-code"> </span><span class="hl-identifier">eat</span><span class="hl-brackets">(</span><span class="hl-brackets">)</span><span class="hl-brackets">{</span><span class="hl-code">
      </span><span class="hl-identifier">System</span><span class="hl-code">.</span><span class="hl-identifier">out</span><span class="hl-code">.</span><span class="hl-identifier">println</span><span class="hl-brackets">(</span><span class="hl-quotes">"</span><span class="hl-string">Mammal eats</span><span class="hl-quotes">"</span><span class="hl-brackets">)</span><span class="hl-code">;
   </span><span class="hl-brackets">}</span><span class="hl-code">

   </span><span class="hl-reserved">public</span><span class="hl-code"> </span><span class="hl-types">void</span><span class="hl-code"> </span><span class="hl-identifier">travel</span><span class="hl-brackets">(</span><span class="hl-brackets">)</span><span class="hl-brackets">{</span><span class="hl-code">
      </span><span class="hl-identifier">System</span><span class="hl-code">.</span><span class="hl-identifier">out</span><span class="hl-code">.</span><span class="hl-identifier">println</span><span class="hl-brackets">(</span><span class="hl-quotes">"</span><span class="hl-string">Mammal travels</span><span class="hl-quotes">"</span><span class="hl-brackets">)</span><span class="hl-code">;
   </span><span class="hl-brackets">}</span><span class="hl-code">

   </span><span class="hl-reserved">public</span><span class="hl-code"> </span><span class="hl-types">int</span><span class="hl-code"> </span><span class="hl-identifier">noOfLegs</span><span class="hl-brackets">(</span><span class="hl-brackets">)</span><span class="hl-brackets">{</span><span class="hl-code">
      </span><span class="hl-reserved">return</span><span class="hl-code"> </span><span class="hl-number">0</span><span class="hl-code">;
   </span><span class="hl-brackets">}</span><span class="hl-code">

   </span><span class="hl-reserved">public</span><span class="hl-code"> </span><span class="hl-types">static</span><span class="hl-code"> </span><span class="hl-types">void</span><span class="hl-code"> </span><span class="hl-identifier">main</span><span class="hl-brackets">(</span><span class="hl-identifier">String</span><span class="hl-code"> </span><span class="hl-identifier">args</span><span class="hl-brackets">[</span><span class="hl-brackets">]</span><span class="hl-brackets">)</span><span class="hl-brackets">{</span><span class="hl-code">
      </span><span class="hl-identifier">MammalInt</span><span class="hl-code"> </span><span class="hl-identifier">m</span><span class="hl-code"> = </span><span class="hl-reserved">new</span><span class="hl-code"> </span><span class="hl-identifier">MammalInt</span><span class="hl-brackets">(</span><span class="hl-brackets">)</span><span class="hl-code">;
      </span><span class="hl-identifier">m</span><span class="hl-code">.</span><span class="hl-identifier">eat</span><span class="hl-brackets">(</span><span class="hl-brackets">)</span><span class="hl-code">;
      </span><span class="hl-identifier">m</span><span class="hl-code">.</span><span class="hl-identifier">travel</span><span class="hl-brackets">(</span><span class="hl-brackets">)</span><span class="hl-code">;
   </span><span class="hl-brackets">}</span><span class="hl-code">
</span><span class="hl-brackets">}</span></pre>
            </div>
        </div>
        <p>以上实例编译运行结果如下:</p>
        <pre class="prettyprint prettyprinted" style=""><span class="typ">Mammal</span><span class="pln"> eats
</span><span class="typ">Mammal</span><span class="pln"> travels</span></pre>
        <p>重写接口中声明的方法时，需要注意以下规则：</p>
        <ul>
            <li>
                类在实现接口的方法时，不能抛出强制性异常，只能在接口中，或者继承接口的抽象类中抛出该强制性异常。</li>
            <li>
                类在重写方法时要保持一致的方法名，并且应该保持相同或者相兼容的返回值类型。</li>
            <li>
                如果实现接口的类是抽象类，那么就没必要实现该接口的方法。</li>
        </ul>
        <p>在实现接口的时候，也要注意一些规则：</p>
        <ul>
            <li>
                一个类可以同时实现多个接口。</li>
            <li>
                一个类只能继承一个类，但是能实现多个接口。</li>
            <li>
                一个接口能继承另一个接口，这和类之间的继承比较相似。</li>
        </ul><hr>
        <h2>
            接口的继承</h2>
        <p>一个接口能继承另一个接口，和类之间的继承方式比较相似。接口的继承使用extends关键字，子接口继承父接口的方法。</p>
        <p>下面的Sports接口被Hockey和Football接口继承：</p><p>
    </p><div class="example">
        <div class="example_code">
            <pre class="hl-main"><span class="hl-comment">//</span><span class="hl-comment"> 文件名: Sports.java</span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-reserved">public</span><span class="hl-code"> </span><span class="hl-reserved">interface</span><span class="hl-code"> </span><span class="hl-identifier">Sports</span><span class="hl-code">
</span><span class="hl-brackets">{</span><span class="hl-code">
   </span><span class="hl-reserved">public</span><span class="hl-code"> </span><span class="hl-types">void</span><span class="hl-code"> </span><span class="hl-identifier">setHomeTeam</span><span class="hl-brackets">(</span><span class="hl-identifier">String</span><span class="hl-code"> </span><span class="hl-identifier">name</span><span class="hl-brackets">)</span><span class="hl-code">;
   </span><span class="hl-reserved">public</span><span class="hl-code"> </span><span class="hl-types">void</span><span class="hl-code"> </span><span class="hl-identifier">setVisitingTeam</span><span class="hl-brackets">(</span><span class="hl-identifier">String</span><span class="hl-code"> </span><span class="hl-identifier">name</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-brackets">}</span><span class="hl-code">

</span><span class="hl-comment">//</span><span class="hl-comment"> 文件名: Football.java</span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-reserved">public</span><span class="hl-code"> </span><span class="hl-reserved">interface</span><span class="hl-code"> </span><span class="hl-identifier">Football</span><span class="hl-code"> </span><span class="hl-reserved">extends</span><span class="hl-code"> </span><span class="hl-identifier">Sports</span><span class="hl-code">
</span><span class="hl-brackets">{</span><span class="hl-code">
   </span><span class="hl-reserved">public</span><span class="hl-code"> </span><span class="hl-types">void</span><span class="hl-code"> </span><span class="hl-identifier">homeTeamScored</span><span class="hl-brackets">(</span><span class="hl-types">int</span><span class="hl-code"> </span><span class="hl-identifier">points</span><span class="hl-brackets">)</span><span class="hl-code">;
   </span><span class="hl-reserved">public</span><span class="hl-code"> </span><span class="hl-types">void</span><span class="hl-code"> </span><span class="hl-identifier">visitingTeamScored</span><span class="hl-brackets">(</span><span class="hl-types">int</span><span class="hl-code"> </span><span class="hl-identifier">points</span><span class="hl-brackets">)</span><span class="hl-code">;
   </span><span class="hl-reserved">public</span><span class="hl-code"> </span><span class="hl-types">void</span><span class="hl-code"> </span><span class="hl-identifier">endOfQuarter</span><span class="hl-brackets">(</span><span class="hl-types">int</span><span class="hl-code"> </span><span class="hl-identifier">quarter</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-brackets">}</span><span class="hl-code">

</span><span class="hl-comment">//</span><span class="hl-comment"> 文件名: Hockey.java</span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-reserved">public</span><span class="hl-code"> </span><span class="hl-reserved">interface</span><span class="hl-code"> </span><span class="hl-identifier">Hockey</span><span class="hl-code"> </span><span class="hl-reserved">extends</span><span class="hl-code"> </span><span class="hl-identifier">Sports</span><span class="hl-code">
</span><span class="hl-brackets">{</span><span class="hl-code">
   </span><span class="hl-reserved">public</span><span class="hl-code"> </span><span class="hl-types">void</span><span class="hl-code"> </span><span class="hl-identifier">homeGoalScored</span><span class="hl-brackets">(</span><span class="hl-brackets">)</span><span class="hl-code">;
   </span><span class="hl-reserved">public</span><span class="hl-code"> </span><span class="hl-types">void</span><span class="hl-code"> </span><span class="hl-identifier">visitingGoalScored</span><span class="hl-brackets">(</span><span class="hl-brackets">)</span><span class="hl-code">;
   </span><span class="hl-reserved">public</span><span class="hl-code"> </span><span class="hl-types">void</span><span class="hl-code"> </span><span class="hl-identifier">endOfPeriod</span><span class="hl-brackets">(</span><span class="hl-types">int</span><span class="hl-code"> </span><span class="hl-identifier">period</span><span class="hl-brackets">)</span><span class="hl-code">;
   </span><span class="hl-reserved">public</span><span class="hl-code"> </span><span class="hl-types">void</span><span class="hl-code"> </span><span class="hl-identifier">overtimePeriod</span><span class="hl-brackets">(</span><span class="hl-types">int</span><span class="hl-code"> </span><span class="hl-identifier">ot</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-brackets">}</span></pre>
        </div>
    </div>
        <p>Hockey接口自己声明了四个方法，从Sports接口继承了两个方法，这样，实现Hockey接口的类需要实现六个方法。</p><p>
        相似的，实现Football接口的类需要实现五个方法，其中两个来自于Sports接口。
    </p><hr>
        <h2>接口的多继承</h2>

        <p>在Java中，类的多继承是不合法，但接口允许多继承，。</p>
        <p>在接口的多继承中extends关键字只需要使用一次，在其后跟着继承接口。
            如下所示：</p>
        <div class="example">
            <div class="example_code">
                <pre class="hl-main"><span class="hl-reserved">public</span><span class="hl-code"> </span><span class="hl-reserved">interface</span><span class="hl-code"> </span><span class="hl-identifier">Hockey</span><span class="hl-code"> </span><span class="hl-reserved">extends</span><span class="hl-code"> </span><span class="hl-identifier">Sports</span><span class="hl-code">, </span><span class="hl-identifier">Event</span></pre>
            </div>
        </div>
        <p>以上的程序片段是合法定义的子接口，与类不同的是，接口允许多继承，而 Sports及  Event 可能定义或是继承相同的方法
        </p>
        <hr><h2>
        标记接口</h2>

        <p>最常用的继承接口是没有包含任何方法的接口。</p>
        <p>标识接口是没有任何方法和属性的接口.它仅仅表明它的类属于一个特定的类型,供其他代码来测试允许做一些事情。</p>
        <p>标识接口作用：简单形象的说就是给某个对象打个标（盖个戳），使对象拥有某个或某些特权。</p>
        <p>例如：java.awt.event 包中的 MouseListener 接口继承的 java.util.EventListener 接口定义如下：</p>
        <div class="example">
            <div class="example_code">
                <pre class="hl-main"><span class="hl-reserved">package</span><span class="hl-code"> </span><span class="hl-identifier">java</span><span class="hl-code">.</span><span class="hl-identifier">util</span><span class="hl-code">;
</span><span class="hl-reserved">public</span><span class="hl-code"> </span><span class="hl-reserved">interface</span><span class="hl-code"> </span><span class="hl-identifier">EventListener</span><span class="hl-code">
</span><span class="hl-brackets">{</span><span class="hl-brackets">}</span></pre>
            </div>
        </div>
        <p>没有任何方法的接口被称为标记接口。标记接口主要用于以下两种目的：
        </p>
        <ul><li><strong>
            建立一个公共的父接口：</strong><p>正如EventListener接口，这是由几十个其他接口扩展的Java API，你可以使用一个标记接口来建立一组接口的父接口。例如：当一个接口继承了EventListener接口，Java虚拟机(JVM)就知道该接口将要被用于一个事件的代理方案。
        </p></li><li><strong>向一个类添加数据类型：</strong><p>这种情况是标记接口最初的目的，实现标记接口的类不需要定义任何接口方法(因为标记接口根本就没有方法)，但是该类通过多态性变成一个接口类型。</p></li></ul>

    </div>
</div>
</body>
</html>
